//
//  HyMessageClient.swift
//  Catnap
//
//  Created by admin on 2022/11/2.
//

import UIKit
import HyphenateChat

class HyMessageClient: NSObject {
    
    //MARK: - Init
    
    /// 是否连接成功（需要在登录之后查询）
    public static var isConnected: Bool {
        guard EMClient.shared().isLoggedIn else { return false }
        return EMClient.shared().isConnected
    }
    
    /// 初始化SDK
    public static func initializeClient() {
        guard let options = EMOptions(appkey: easyMobileKey) else {return}
        options.apnsCertName = nil
        EMClient.shared().initializeSDK(with: options)
    }
    
    /// 绑定deviceToken
    /// - Parameter deviceToken: 设备token
    public static func binding(_ deviceToken: Data?) {
        guard let token = deviceToken else { return }
        EMClient.shared().bindDeviceToken(token)
    }
    
    /// 添加设备代理
    /// - Parameter aDelegate: 代理
    public static func addDelegate(aDelegate: EMClientDelegate!) {
        EMClient.shared().add(aDelegate, delegateQueue: nil)
    }
    
    /// 添加聊天代理
    /// - Parameter aDelegate: 代理
    public static func addChatDelegate(aDelegate: EMChatManagerDelegate!) {
        EMClient.shared().chatManager?.add(aDelegate, delegateQueue: nil)
    }
    
    /// 更新用户自己的信息
    /// - Parameters:
    ///   - userId: 用户ID
    ///   - nickName: 名称
    ///   - avatarUrl: 头像
    ///   - gender: 性别，0为未设置
    ///   - signature: 签名
    ///   - birthday: 生日
    public static func updateUserInfo(_ userId: Int, _ nickName: String, _ avatarUrl: String, _ gender: Int, _ signature: String, _ birthday: String) {
        guard userId > 0 else { return }
        guard EMClient.shared().isLoggedIn else { return }
        let info = EMUserInfo()
        info.userId = "\(userId)"
        info.nickname = nickName
        info.avatarUrl = avatarUrl
        info.gender = gender
        info.sign = signature
        info.birth = birthday
        EMClient.shared().userInfoManager.updateOwn(info) { aUserInfo, aError in
            if let userInfo = aUserInfo {
                debugPrint("[环信] - [更新本地用户信息成功] - %@", userInfo)
            }
            if let error = aError {
                debugPrint("[环信] - [更新本地用户信息失败] - [aError:%@]", error.errorDescription ?? "")
            }
        }
    }
    
    /// 查询用户信息
    /// - Parameters:
    ///   - userId: 用户ID
    ///   - completion: 完成回调
    public static func queryUserInfo(_ userId: Int, completion : @escaping (_ userInfo : [AnyHashable : Any]?, _ error: EMError?)->()) {
        guard userId > 0 else { return }
        EMClient.shared().userInfoManager.fetchUserInfo(byId: ["\(userId)"]) { userInfo, aError in
            completion(userInfo, aError)
        }
    }
    
    /// 程序退到后台告诉环信服务器
    /// - Parameter application: application
    public static func applicationDidEnterBackground(_ application: UIApplication) {
        EMClient.shared().applicationDidEnterBackground(application)
    }
    
    /// 程序进入前台告诉环信服务器
    /// - Parameter application: application
    public static func applicationWillEnterForeground(_ application: UIApplication) {
        EMClient.shared().applicationWillEnterForeground(application)
    }
    
    /// 登录环信
    /// - Parameters:
    ///   - userId: 用户ID
    ///   - password: 此项目与账号一致
    ///   - completion: 完成回调
    public static func login(_ userId: Int, _ password: Int?, completion : @escaping (_ userInfo: String?, _ error: EMError?)->()) {
        guard userId > 0 else { return }
        guard !EMClient.shared().isLoggedIn else {
            completion("AlreadyLogin", nil)
            debugPrint("[环信] - [AlreadyLogin] - [用户已经登录]")
            self.logout()
            self.login(userId, password) { userInfo, error in
                
            }
            return
        }
        var name: String?
        var pass: String?
        name = "\(userId)"
        if password == nil {
            pass = name
        }else {
            pass = "\(password ?? 0)"
        }
        EMClient.shared().register(withUsername: name, password: pass) { s, e in
            
            print("register==-=== ")
            print(e?.errorDescription)
            print(e?.code)
    
            EMClient.shared().login(withUsername: name, password: pass) { aUsername, aError in
                if let error = aError {
                    debugPrint("[环信] - 登录失败:" + error.errorDescription)
                    debugPrint(error.code)
                    completion(aUsername, aError)
                }else {
                    debugPrint("[环信] - [用户: " + (aUsername ?? "") + "] - 登录成功")
                    completion(aUsername, nil)
                }
            }
        }

    }

    /// 退出环信登录
    /// - Parameter deleteDeviceToken: 是否删除设备token
    public static func logout(_ deleteDeviceToken: Bool = true) {
        EMClient.shared().logout(deleteDeviceToken)
    }
    
    //MARK: - Send Messages
    
    /// 发送文本消息
    /// - Parameters:
    ///   - message: 消息内容
    ///   - toPeerId: 对方ID，需要加上‘vivi’前缀
    ///   - ext: 附加信息
    ///   - completion: 完成回调
    /// - Returns: EMMessage
    public static func sendTextMessage(_ message: String, _ toPeerId: Int, _ ext: [String: Any]?, completion: @escaping (_ message: EMChatMessage) -> ()) {
        guard toPeerId > 0, let body = EMTextMessageBody(text: message) else { return }
        sendMessageBody(body, toPeerId, ext, completion: completion)
    }
    
    /// 发送图片消息
    /// - Parameters:
    ///   - image: 图片
    ///   - toPeerId: 对方ID，需要加上‘vivi’前缀
    ///   - completion: 完成回调
    /// - Returns: EMMessage
    public static func sendImageMessage(_ image: UIImage, _ toPeerId: Int, completion: @escaping (_ message: EMChatMessage) -> ()) {
        guard toPeerId > 0 else { return }
        guard let body = EMImageMessageBody(data: image.pngData(), thumbnailData: image.pngData()) else {return}
        sendMessageBody(body, toPeerId, nil, completion: completion)
    }
    
    /// 发送自定义消息
    /// - Parameters:
    ///   - eventName: 事件名称
    ///   - toPeerId: 对方ID，需要加上‘vivi’前缀
    ///   - params: 参数
    ///   - completion: 完成回调
    /// - Returns: EMMessage
    public static func sendCustomMessage(_ eventName: String, _ toPeerId: Int, _ params: [String: Any]?, completion: @escaping (_ message: EMChatMessage) -> ()) {
        guard toPeerId > 0 else { return }
        guard let body = EMCustomMessageBody(event: eventName, ext: params) else {return}
        sendMessageBody(body, toPeerId, nil, completion: completion)
    }
    
    /// 发送透传消息（一般用于视频信令消息，不会在数据库中存储）
    /// - Parameters:
    ///   - action: 事件
    ///   - toPeerId: 对方ID，需要加上‘vivi’前缀
    ///   - ext: 附加信息
    ///   - completion: 完成回调
    public static func sendCMDMessage(_ action: String, _ toPeerId: Int, _ ext: [String: Any]?, completion: @escaping () -> ()) {
        guard toPeerId > 0 else { return }
        guard let body = EMCmdMessageBody(action: action),
              let msg = EMChatMessage(conversationID: "\(toPeerId)", from: EMClient.shared().currentUsername, to: "\(toPeerId)", body: body, ext: ext) else { return }
        msg.chatType = EMChatTypeChat
        EMClient.shared().chatManager?.send(msg, progress: nil) { aMessage, aError in
            if let message = aMessage {
                debugPrint("[环信] - [发送消息成功]- %@", message)
                completion()
            }
            if let error = aError {
                debugPrint("[环信] - [发送消息失败]- %@", error.errorDescription ?? "")
            }
        }
    }
    
    /// 发送消息
    /// - Parameters:
    ///   - body: 消息体
    ///   - peerId: 接收方ID，需要加上‘vivi’前缀
    ///   - ext: 附加信息
    ///   - completion: 完成回调
    /// - Returns: EMMessage
    static func sendMessageBody(_ body: EMMessageBody, _ peerId: Int, _ ext: [String: Any]?, completion: @escaping (_ message: EMChatMessage) -> ()) {
        guard let msg = EMChatMessage(conversationID: "\(peerId)", from: EMClient.shared().currentUsername, to: "\(peerId)", body: body, ext: ext) else { return }
        msg.chatType = EMChatTypeChat
        EMClient.shared().chatManager?.send(msg, progress: nil) { aMessage, aError in
            if let message = aMessage {
                debugPrint("[环信] - [发送消息成功]- %@", message)
                completion(message)
            }
            if let error = aError {
                debugPrint("[环信] - [发送消息失败]- %@", error.errorDescription ?? "")
            }
        }
    }
    
    /// 下载文件
    /// - Parameters:
    ///   - message: 需要下载的消息
    ///   - completion: 完成回调
    ///   - progress: 下载进度
    public static func downLoadFile(_ message: EMChatMessage, completion: @escaping (_ message: EMChatMessage?, _ error: EMError?) -> (), _ progress: @escaping ((_ pro: Int32) -> ())) {
        EMClient.shared().chatManager?.downloadMessageThumbnail(message, progress: progress) { message, aError in
            completion(message, aError)
        }
    }
    
    //MARK: - Conversation
    
    /// 查询用户会话
    /// - Parameter userId: 用户ID，需要加上‘vivi’前缀
    /// - Returns: 用户会话
    public static func queryConversation(_ userId: Int) -> EMConversation? {
        guard userId > 0 else { return nil }
        guard let conversation = EMClient.shared().chatManager?.getConversationWithConvId("\(userId)") else {
            return EMClient.shared().chatManager?.getConversation("\(userId)", type: EMConversationTypeChat, createIfNotExist: true)
        }
        return conversation
    }
    
    /// 查询所有会话
    /// - Returns: 会话数组
    public static func queryAllConversation() -> [EMConversation]? {
        guard let conversations = EMClient.shared().chatManager?.getAllConversations() as? [EMConversation] else { return nil }
        return conversations
    }
    
    /// 删除会话
    /// - Parameters:
    ///   - conversationId: 会话ID
    ///   - isDeleteMessages: 是否删除消息
    ///   - completion: 完成回调
    public static func deleteConversation(_ conversationId: String, _ isDeleteMessages: Bool, completion: @escaping (_ conversationId: String?, _ error: EMError?) -> ()) {
        EMClient.shared().chatManager?.deleteConversation(conversationId, isDeleteMessages: isDeleteMessages) { converId, aError in
            completion(converId, aError)
        }
    }
    
    /// 查询会话的未读消息数
    /// - Parameter conversationId: 会话ID
    /// - Returns: 会话的未读消息数
    public static func queryUnredMessages(_ conversationId: String?) -> Int32? {
        guard let conversation = EMClient.shared().chatManager?.getConversation(conversationId, type: EMConversationTypeChat, createIfNotExist: true) else {return nil}
        return conversation.unreadMessagesCount
    }
    
    /// 查询所有未读消息数
    /// - Returns: 未读消息数
    public static func queryAllUnreadCount() -> Int32? {
        if let conversations = queryAllConversation() {
            var unreadCount: Int32 = 0
            for i in 0..<conversations.count {
                let model = conversations[i]
                if model.unreadMessagesCount > 0 {
                    unreadCount += model.unreadMessagesCount
                }
            }
            return unreadCount
        }
        return nil
    }
    
    /// 清除会话中所有未读消息数
    /// - Parameter conversation: 会话
    public static func clearAllUnreadMessage(_ conversation: EMConversation) {
        guard conversation.unreadMessagesCount > 0 else { return }
        conversation.markAllMessages(asRead: nil)
    }
    
}
